package com.xlh.virtualization.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xlh.virtualization.dao.ext.ContainerMapperExt;
import com.xlh.virtualization.dao.helper.ContainerMapperHelper;
import com.xlh.dokka.api.DokkaContainerService;
import com.xlh.virtualization.domain.*;
import com.xlh.virtualization.service.ContainerService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.xlh.virtualization.constant.ContainerStatusEnum.EXITED;

/**
 * @author cheer
 */
@Service
public class ContainerServiceImpl implements ContainerService {

    @Autowired
    private DokkaContainerService dokkaContainerService;

    @Autowired
    private ContainerMapperExt containerMapperExt;

    @Autowired
    private ContainerMapperHelper containerMapperHelper;

    @Override
    public PageInfo<ContainerAttr> listContainersByPage(Integer pageNum, Integer pageSize, String userInfo, List<Integer> status) {
        PageHelper.startPage(pageNum, pageSize);
        List<ContainerAttr> containerAttrs = containerMapperExt.listContainers(userInfo, status);
        return new PageInfo<>(containerAttrs);
    }

    @Override
    public PageInfo<ContainerCourseAttr> listCourseContainersByPage(Long courseId, Integer pageNum, Integer pageSize,
                                                                    String userInfo, List<Integer> status) {
        PageHelper.startPage(pageNum, pageSize);
        List<ContainerCourseAttr> containerCourseAttrs = containerMapperExt.listCourseContainers(userInfo, status, courseId);
        return new PageInfo<>(containerCourseAttrs);
    }

    @Override
    public PageInfo<ContainerTrainingAttr> listTrainingContainersByPage(Integer pageNum, Integer pageSize,
                                                                        String userInfo, List<Integer> status) {
        PageHelper.startPage(pageNum, pageSize);
        List<ContainerTrainingAttr> containerTrainingAttrs = containerMapperExt.listTrainingContainers(userInfo, status);
        return new PageInfo<>(containerTrainingAttrs);
    }

    @Override
    public void deleteContainer(Container container) {
        containerMapperHelper.deleteById(container.getId());
        dokkaContainerService.deleteContainer(container.getDokkaId());
    }

    @Override
    public void deleteContainer(List<Container> containers) {
        List<Long> deletedIds = new ArrayList<>();
        for (Container container : containers) {
            deletedIds.add(container.getId());
            dokkaContainerService.deleteContainer(container.getDokkaId());
        }
        containerMapperHelper.deleteByIds(deletedIds);
    }

    @Override
    public void deleteExitedContainers(List<Long> containerIds) {
        if (CollectionUtils.isEmpty(containerIds)) {
            return;
        }
        List<Container> containers = containerMapperHelper.listExitedContainers(containerIds);
        List<Long> deletedIds = new ArrayList<>();
        for (Container container : containers) {
            dokkaContainerService.deleteContainer(container.getDokkaId());
            deletedIds.add(container.getId());
        }
        containerMapperHelper.deleteByIds(deletedIds);
    }

    @Override
    public void deleteContainerByContext(ContainerContext containerContext) {
        List<Container> containers = containerMapperHelper.listContainersByContext(containerContext.getUserId(),
                containerContext.getContextType(), containerContext.getContextId());
        deleteContainer(containers);
    }

    @Override
    public void deleteExtraContainerByContext(ContainerContext containerContext, List<Long> containerIds) {
        List<Container> containers = containerMapperHelper.listExtraContainersByContext(containerContext.getUserId(),
                containerContext.getContextType(), containerContext.getContextId(), containerIds);
        deleteContainer(containers);
    }

    @Override
    public void stopContainer(Container container) {
        if (dokkaContainerService.stopContainer(container.getDokkaId())) {
            containerMapperHelper.updateStatus(container.getId(), EXITED.getCode());
        }
    }

    @Override
    public void stopContainer(List<Container> containers) {
        List<Long> stoppedContainerIds = containers.stream()
                .filter(container -> dokkaContainerService.stopContainer(container.getDokkaId()))
                .map(Container::getId)
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(stoppedContainerIds)) {
            containerMapperHelper.updateStatus(stoppedContainerIds, EXITED.getCode());
        }
    }

    @Override
    public void stopContainerByContext(ContainerContext containerContext) {
        List<Container> containers = containerMapperHelper.listContainersByContext(containerContext.getUserId(),
                containerContext.getContextType(), containerContext.getContextId());
        stopContainer(containers);
    }

    /*-------   下面3个接口用于 课程服务删除容器 为了提高处理效率异步处理  -------*/

    @Override
    @Async
    public void deleteContainerByContext(Integer contextType, Long contextId) {
        List<Container> containers = containerMapperHelper.listContainersByContext(contextType, contextId);
        deleteContainer(containers);
    }

    @Override
    @Async
    public void deleteContainerByContext(Integer contextType, List<Long> contextIds, List<Long> userIds) {
        List<Container> containers = containerMapperHelper.listContainersByContext(contextType, contextIds, userIds);
        deleteContainer(containers);
    }

    @Override
    @Async
    public void trueDeleteContainerByContext(Integer contextType, Long contextId) {
        List<Container> containers = containerMapperHelper.listContainersByContext(contextType, contextId);
        List<Long> deletedIds = new ArrayList<>();
        for (Container container : containers) {
            deletedIds.add(container.getId());
            dokkaContainerService.deleteContainer(container.getDokkaId());
        }
        containerMapperHelper.trueDeleteByIds(deletedIds);
    }

    /*-------   end   -------*/
}
